import React, { StrictMode, useState, useRef, useImperativeHandle, useContext } from 'react'
import classnames from 'classnames'
import '../styles/less/common.less'

export class SetstateTemplate extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            count: 0,
            count1: 0,
            count2: 0,
            count3: 0,
            message: 'cccccc',
        }
    }

    // +++++++++++++++++++++++++++++ 总结 +++++++++++++++++++++++++++++++++
    // 在绝大多数场景下，setState呈现出异步的行为模式。这意味着，当调用setState时，组件状态并不会立即更新，
    // React 会对多个setState调用进行批量处理，以优化性能。 连续调用setState, 组件只会update一次

    // +++++++++++++++++++++++++++++ setState异步, setState(object) +++++++++++++++++++++++++++++++++
    incrementCount() {
        // 注意：这样 *不会* 像预期的那样工作。
        this.setState({ count: this.state.count + 1 });
    }
    handleSomething() {
        // 假设 `this.state.count` 从 0 开始。
        this.incrementCount();
        console.log(111111, this.state.count)
        this.incrementCount();
        console.log(222222, this.state.count)
        this.incrementCount();
        console.log(333333, this.state.count)
        // 当 React 重新渲染该组件时，`this.state.count` 会变为 1，而不是你期望的 3。
        // 这是因为上面的 `incrementCount()` 函数是从 `this.state.count` 中读取数据的，
        // 但是 React 不会更新 `this.state.count`，直到该组件被重新渲染。
        // 所以最终 `incrementCount()` 每次读取 `this.state.count` 的值都是 0，并将它设为 1。
    }

    // +++++++++++++++++++++++++++++ setState异步, setState(updaterFun) +++++++++++++++++++++++++++++++++
    incrementCount1() {
        // 传递一个函数可以让你在函数内访问到当前的 state 的值。
        // 因为 setState 的调用是分批的，所以你可以链式地进行更新，并确保它们是一个建立在另一个之上的，这样才不会发生冲突：
        this.setState((state) => {
            // 重要：在更新的时候读取 `state`，而不是 `this.state`。
            return { count1: state.count1 + 1 }
        });
    }

    handleSomething1() {
        // 假设 `this.state.count` 从 0 开始。
        this.incrementCount1();
        console.log(111111, this.state.count1)
        this.incrementCount1();
        console.log(222222, this.state.count1)
        this.incrementCount1();
        console.log(333333, this.state.count1)

        // 如果你现在在这里读取 `this.state.count`，它还是会为 0。
        // 但是，当 React 重新渲染该组件时，它会变为 3。
    }

    // +++++++++++++++++++++++++++++ 旧版本setState同步??? +++++++++++++++++++++++++++++++++
    incrementCount2() {
        // this.setState((state) => {
        //     // 重要：在更新的时候读取 `state`，而不是 `this.state`。
        //     return { count2: state.count2 + 1 }
        // });
        this.setState({ count2: this.state.count2 + 1 });
    }

    // +++++++++++++++++++++++++++++ setState回调获取新数据 +++++++++++++++++++++++++++++++++
    incrementCount3() {
        this.setState((state) => {
            return { count3: state.count3 + 1 }
        }, () => {
            console.log('incrementCount3...', this.state.count3)
        });
    }
    handleSomething3() {
        // 假设 `this.state.count` 从 0 开始。
        this.incrementCount3();
        console.log(111111, this.state.count3)
        this.incrementCount3();
        console.log(222222, this.state.count3)
        this.incrementCount3();
        console.log(333333, this.state.count3)

        // 如果你现在在这里读取 `this.state.count`，它还是会为 0。
        // 但是，当 React 重新渲染该组件时，它会变为 3。
    }
    componentDidMount() {
        console.log('componentDidMount...')

        // react18中没有同步???
        // document.addEventListener('click', () => {
        //     this.setState({
        //         message: 'Updated in native event'
        //     });
        //     console.log(this.state.message);
        // });

        // setTimeout(() => {
        //     this.incrementCount2();
        //     console.log(111111, this.state.count2)
        //     this.incrementCount2();
        //     console.log(222222, this.state.count2)
        //     this.incrementCount2();
        //     console.log(333333, this.state.count2)
        // }, 0)
    }
    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log('componentDidUpdate...', prevProps, prevState, snapshot, this.state)
    }
    render() {
        return (
            <div className='boxStyle' >
                <p className={classnames('colorBlue', 'fontSize12')}>setState的同步与异步</p>
                <p>当前count的值:{this.state.count}</p>
                <p>当前count1的值:{this.state.count1}</p>
                <p>当前count2的值:{this.state.count2}</p>
                <p>当前count3的值:{this.state.count3}</p>
                <button onClick={() => this.handleSomething()} >
                    直接setState对象
                </button>
                <button onClick={() => this.handleSomething1()} >
                    通过setState函数处理
                </button>
                <button onClick={() => this.handleSomething3()} >
                    通过回调获取更新值
                </button>
            </div>
        )
    }
}


